define([
    'app',
    'json2',
    'clipboard',
    'sql-formatter',
    'standalone',
    'parser-babylon',
    'parser-yaml',
    'parser-postcss',
    'parser-html',
    'parser-typescript',
    'jquery.format',
    'ace-language-tools'
], function(app, JSON2, Clipboard, sqlFormatter, prettier, babylonPlugins, yamlPlugins, postcssPlugins,
        htmlPlugins, typescriptPlugins) {
    var prettierPlugins = {
            'babylon': babylonPlugins,
            'yaml': yamlPlugins,
            'postcss': postcssPlugins,
            'html': htmlPlugins,
            'typescript': typescriptPlugins
        };

    app.controller('TextFormatterController', function($scope, $timeout, toastr) {
        var self = this;
        self.data = '';
        self.code = '';
        self.error = '';
        self.showConfig = true;

        // data type
        self.dataTypes = [{
            value: 'css', label: 'CSS', parser: 'css'
        }, {
            value: 'html', label: 'HTML', parser: 'html'
        }, {
            value: 'json', label: 'JSON', parser: JSON2.format
        }, {
            value: 'javascript', label: 'JavaScript', parser: 'typescript'
        }, {
            value: 'less', label: 'LESS', parser: 'less'
        }, {
            value: 'scss', label: 'SCSS', parser: 'scss'
        }, {
            value: 'sql', label: 'SQL', parser: sqlFormatter.format
        }, {
            value: 'xml', label: 'XML', parser: 'html'
        }, {
            value: 'yaml', label: 'YAML', parser: 'yaml'
        }];
        self.dataType = self.dataTypes[2];

        self.config = {
            printWidth: 80,
            tabWidth: 4,
            useTabs: false,
            singleQuote: false,
            bracketSpacing: true,
            proseWrap: 'preserve',
            semi: true,
            jsxSingleQuote: false,
            jsxBracketSameLine: false,
            arrowParens: 'avoid',
            trailingComma: 'es5',
            htmlWhitespaceSensitivity: 'ignore',
            insertPragma: false,
            requirePragma: false,
            plugins: prettierPlugins
        };

        var dataEditor = null;

        self.init = function() {
            self.data = '{"username":"admin","password":"123456"}';

            new Clipboard('#copy', {
                text: function() {
                    return self.code;
                }
            }).on('success', function(e) {
                toastr.success('已复制到剪贴板！');
            });

            $timeout(function() {
                // data editor
                dataEditor = ace.edit('data-editor');
                dataEditor.setOptions({
                    mode: 'ace/mode/json',
                    fontSize: 13,
                    showPrintMargin: true,
                    autoScrollEditorIntoView: true,
                    enableBasicAutocompletion: true,
                    enableSnippets: true,
                    enableLiveAutocompletion: true
                });
                $timeout(function() {
                    dataEditor.resize();
                });

                $scope.$watch('vm.code', function(newValue) {
                    var modeId = 'ace/mode/' + self.dataType.value;
                    if (modeId != dataEditor.getOption('mode')) {
                        dataEditor.setValue('', -1);
                        dataEditor.getSession().setMode(modeId);
                    }
                    setTimeout(function() {
                        dataEditor.setValue(newValue, -1);
                        dataEditor.resize();
                    }, 200);
                });

                $scope.$watch('vm.config.printWidth', function(newValue) {
                    if (newValue >= 0) {
                        dataEditor.setOption('printMargin', newValue);
                        dataEditor.setOption('printMarginColumn', newValue);
                    }
                });
            });
        }

        self.format = function(valid) {
            self.error = '';
            if (valid) {
                if (/^\s*$/.test(self.data)) {
                    self.code = '';
                } else {
                    try {
                        if (self.dataType.value == 'json') {
                            self.code = self.dataType['parser'](self.data, getIndents());
                        } else if (self.dataType.value == 'sql') {
                            self.code = self.dataType['parser'](self.data, {
                                indent: getIndents(),
                                language: 'sql'
                            });
                        } else {
                            self.config['parser'] = self.dataType['parser'];
                            self.code = prettier.format(self.data, self.config);
                        }
                    } catch (e) {
                        self.code = '';
                        self.error = e;
                    }
                }
            }
        }

        function getIndents() {
            return self.config.useTabs ? '\t' : _.map(_.range(self.config.tabWidth), function() {
                return ' ';
            }).join('');
        }

        self.reset = function() {
            self.dataType = self.dataTypes[0];
            self.data = '';
            self.code = '';
            self.error = '';
            self.config = {
                printWidth: 80,
                tabWidth: 4,
                useTabs: false,
                singleQuote: false,
                bracketSpacing: true,
                proseWrap: 'preserve',
                semi: true,
                jsxSingleQuote: false,
                jsxBracketSameLine: false,
                arrowParens: 'avoid',
                trailingComma: 'es5',
                htmlWhitespaceSensitivity: 'ignore',
                insertPragma: false,
                requirePragma: false,
                plugins: prettierPlugins
            };
        }
    });
});
